<#assign object = doc.object>
package ${object.package}.service.base;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import redora.rdo.api.BusinessRuleViolation;
import redora.rdo.api.FetchScope;
import redora.rdo.exceptions.PersistenceException;
import ${object.package}.model.${object.name};
import ${object.package}.service.*;
import redora.rdo.util.BusinessRuleJSON;

/**
* This servlet dispatches standard retrieve / insert / update and delete operations on the ${object.name} object.
* This class is extended by ${object.name}Servlet, so if you want to modify the behavior of this class, please change that file.
* @see ${object.package}.service.http.${object.name}Servlet;
*/
public class ${object.name}ServletBase extends HttpServlet {
  	private Logger l = Logger.getLogger("${object.package}.service.base.${object.name}ServletBase");
  	private ${object.name}ServiceJSON serviceJSON;
  	private ${object.name}Service service;

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		try {
			<#if object.name == "RedoraConfiguration">
			//TODO move this to the final Servlet!
			Upgrade upgrade = new Upgrade();
			if (req.getParameter("_operationType").equalsIgnoreCase("upgradeTable")) {
				upgrade.upgradeTable(resp.getWriter());
			}
			if (req.getParameter("_operationType").equalsIgnoreCase("fetch")) {
				upgrade.initDefaultScript();
				serviceJSON.findAll(FetchScope.Table,resp.getWriter());
				resp.getWriter().flush();
			}
			if (req.getParameter("_operationType").equalsIgnoreCase("update")) {
				${object.name} ${object.name?uncap_first} = serviceJSON.fromJson(${object.name}Util.getJSONValue(req));
				Set<BusinessRuleViolation> ret = service.persist(${object.name?uncap_first});
				if (ret.isEmpty()) {
					${object.name}Util.copy(${object.name?uncap_first}, resp.getWriter());
					//TODO create the copy function
				} else {
					BusinessRuleJSON.copy(ret, resp.getWriter());
				}
				resp.getWriter().flush();
			}
			<#else>
			if (req.getParameter("_operationType").equalsIgnoreCase("fetch")) {
				Map params = req.getParameterMap();
				if("true".equalsIgnoreCase(req.getParameter("findByParams"))) {
					if (FetchScope.List.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findByParams(params,FetchScope.List,resp.getWriter());
					else if (FetchScope.Table.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findByParams(params,FetchScope.Table,resp.getWriter());
					else if (FetchScope.Form.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findByParams(params,FetchScope.Form,resp.getWriter());
					else if (FetchScope.Lazy.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findByParams(params,FetchScope.Lazy,resp.getWriter());
				}
				else {
					if(FetchScope.List.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findAll(FetchScope.List,resp.getWriter());
					else if (FetchScope.Table.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findAll(FetchScope.Table,resp.getWriter());
					else if (FetchScope.Form.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findAll(FetchScope.Table,resp.getWriter());
					else if (FetchScope.Lazy.name().equalsIgnoreCase(req.getParameter("fetchScope")))
						serviceJSON.findAll(FetchScope.Lazy,resp.getWriter());
				}
				resp.getWriter().flush();
			} else if (req.getParameter("_operationType").equalsIgnoreCase("persist")) {
				${object.name} ${object.name?uncap_first} = serviceJSON.fromJson(${object.name}Util.getJSONValue(req));
				Set<BusinessRuleViolation> ret = service.persist(${object.name?uncap_first});
				if (ret.isEmpty()) {
					${object.name}Util.copy(${object.name?uncap_first}, resp.getWriter());
				} else {
					resp.getWriter().print('{');
					resp.getWriter().print("response:");
					resp.getWriter().print('{');
					resp.getWriter().print("status:-1,error:");
					BusinessRuleJSON.copy(ret, resp.getWriter());
					resp.getWriter().print('}');
					resp.getWriter().print('}');
				}
				resp.getWriter().flush();
			} else if (req.getParameter("_operationType").equalsIgnoreCase("remove")) {
				${object.name} ${object.name?uncap_first} = serviceJSON.fromJson(${object.name}Util.getJSONValue(req));
				Set<BusinessRuleViolation> ret = service.delete(${object.name?uncap_first});
				resp.getWriter().print('{');
				resp.getWriter().print("response:");
				resp.getWriter().print('{');
				if (!ret.isEmpty()) {
					resp.getWriter().print("status:-1,error:");
					BusinessRuleJSON.copy(ret, resp.getWriter());
				} else {
					resp.getWriter().print("status:0");
				}
				resp.getWriter().print('}');
				resp.getWriter().print('}');
				resp.getWriter().flush();
			} 
				<#if object.trashcan[0]?? && object.trashcan == "true">
			if (req.getParameter("_operationType").equalsIgnoreCase("trash")) {
				${object.name} ${object.name?uncap_first} = serviceJSON.fromJson(${object.name}Util.getJSONValue(req));
				Set<BusinessRuleViolation> ret = service.trash(null,${object.name?uncap_first});
				resp.getWriter().print('{');
				resp.getWriter().print("response:");
				resp.getWriter().print('{');
				if (!ret.isEmpty()) {
					resp.getWriter().print("status:-1,error:");
					BusinessRuleJSON.copy(ret, resp.getWriter());
				} else {
					resp.getWriter().print("status:0");
				}
				resp.getWriter().print('}');
				resp.getWriter().print('}');
				resp.getWriter().flush();
			} 
			if (req.getParameter("_operationType").equalsIgnoreCase("undo")) {
				service.undo(Long.valueOf(req.getParameter("id")));
				resp.getWriter().print('{');
				resp.getWriter().print("response:");
				resp.getWriter().print('{');
				resp.getWriter().print("status:0");
				resp.getWriter().print('}');
				resp.getWriter().print('}');
				resp.getWriter().flush();
			} 
				</#if>
				<#if object.lazyScope[0]??>
			if (req.getParameter("_operationType").equalsIgnoreCase("fetchLazy")) {
				long id = Long.valueOf(req.getParameter("id"));
				serviceJSON.fetchLazy(id, resp.getWriter());
			}
				</#if>
			</#if>
		} catch (Exception e) {
			resp.getWriter().print('{');
			resp.getWriter().print("response:");
			resp.getWriter().print('{');
			resp.getWriter().print("status:-2,error:");
			resp.getWriter().print("\"");
			resp.getWriter().print(
					"I failed to process a JSON request: "
							+ req.getParameter("_operationType") + ". Reason: " + e.getMessage());
			resp.getWriter().print("\"");
			resp.getWriter().print('}');
			resp.getWriter().print('}');
			resp.getWriter().flush();
			l.log(Level.SEVERE, "I failed to process a JSON request: " + req.getParameter("_operationType"), e);
			throw new ServletException("I failed to process a JSON request: " + req.getParameter("_operationType"), e);
		}
	}
	
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}

	@Override
	public void init() throws ServletException {
	  try {
	    serviceJSON = ServiceFactory.${object.name?uncap_first}ServiceJSON();
	    service = ServiceFactory.${object.name?uncap_first}Service();
	  } catch (PersistenceException e) {
	    l.log(Level.SEVERE, "Failed to initialize", e);
	  }
	  super.init();
	}
}
